const Gio = imports.gi.Gio;
const Lang = imports.lang;
-const Shell = imports.gi.Shell;
+const NMGtk = imports.gi.NMGtk;
const Signals = imports.signals;
-
-// _getProvidersTable:
-//
-// Gets the table of references between MCCMNC and operator name
-//
-let _providersTable;
-function _getProvidersTable() {
- if (_providersTable)
- return _providersTable;
- return _providersTable = Shell.mobile_providers_parse(null,null);
-}
-
-// findProviderForMCCMNC:
-// @table: a table of country code keys and Shell.CountryMobileProvider values
-// @needle: operator code, given as MCCMNC string
+// _getMobileProvidersDatabase:
//
-// Tries to find the operator name corresponding to the given MCCMNC
+// Gets the database of mobile providers, with references between MCCMNC/SID and
+// operator name
//
-function findProviderForMCCMNC(table, needle) {
- let needlemcc = needle.substring(0, 3);
- let needlemnc = needle.substring(3, needle.length);
-
- let name2, name3;
- for (let iter in table) {
- let country = table[iter];
- let providers = country.get_providers();
-
- // Search through each country's providers
- for (let i = 0; i < providers.length; i++) {
- let provider = providers[i];
-
- // Search through MCC/MNC list
- let list = provider.get_gsm_mcc_mnc();
- for (let j = 0; j < list.length; j++) {
- let mccmnc = list[j];
-
- // Match both 2-digit and 3-digit MNC; prefer a
- // 3-digit match if found, otherwise a 2-digit one.
- if (mccmnc.mcc != needlemcc)
- continue; // MCC was wrong
-
- if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
- name3 = provider.name;
-
- if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
- name2 = provider.name;
-
- if (name2 && name3)
- break;
- }
+let _mpd;
+function _getMobileProvidersDatabase() {
+ if (_mpd == null) {
+ try {
+ _mpd = new NMGtk.MobileProvidersDatabase();
+ _mpd.init(null);
+ } catch (e) {
+ log(e.message);
+ _mpd = null;
}
}
- return name3 || name2 || null;
+ return _mpd;
}
-// findOperatorName:
+// _findProviderForMccMnc:
// @operator_name: operator name
// @operator_code: operator code
//
// Given an operator name string (which may not be a real operator name) and an
// operator code string, tries to find a proper operator name to display.
//
-function findOperatorName(operator_name, operator_code) {
+function _findProviderForMccMnc(operator_name, operator_code) {
if (operator_name) {
if (operator_name.length != 0 &&
(operator_name.length > 6 || operator_name.length < 5)) {
else // nothing to search
return null;
- let table = _getProvidersTable();
- return findProviderForMCCMNC(table, needle);
+ let mpd = _getMobileProvidersDatabase();
+ if (mpd) {
+ let provider = mpd.lookup_3gpp_mcc_mnc(needle);
+ if (provider)
+ return provider.get_name();
+ }
+ return null;
}
-// findProviderForSid:
-// @table: a table of country code keys and Shell.CountryMobileProvider values
+// _findProviderForSid:
// @sid: System Identifier of the serving CDMA network
//
// Tries to find the operator name corresponding to the given SID
//
-function findProviderForSid(table, sid) {
+function _findProviderForSid(sid) {
if (sid == 0)
return null;
- // Search through each country
- for (let iter in table) {
- let country = table[iter];
- let providers = country.get_providers();
-
- // Search through each country's providers
- for (let i = 0; i < providers.length; i++) {
- let provider = providers[i];
- let cdma_sid = provider.get_cdma_sid();
-
- // Search through CDMA SID list
- for (let j = 0; j < cdma_sid.length; j++) {
- if (cdma_sid[j] == sid)
- return provider.name;
- }
- }
+ let mpd = _getMobileProvidersDatabase();
+ if (mpd) {
+ let provider = mpd.lookup_cdma_sid(sid);
+ if (provider)
+ return provider.get_name();
}
-
return null;
}
+
//------------------------------------------------------------------------------
// Support for the old ModemManager interface (MM < 0.7)
//------------------------------------------------------------------------------
this.emit('notify::signal-quality');
}));
this._proxy.connectSignal('RegistrationInfo', Lang.bind(this, function(proxy, sender, [status, code, name]) {
- this.operator_name = findOperatorName(name, code);
+ this.operator_name = _findProviderForMccMnc(name, code);
this.emit('notify::operator-name');
}));
this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function([result], err) {
}
let [status, code, name] = result;
- this.operator_name = findOperatorName(name, code);
+ this.operator_name = _findProviderForMccMnc(name, code);
this.emit('notify::operator-name');
}));
this._proxy.GetSignalQualityRemote(Lang.bind(this, function(result, err) {
// it will return an error if the device is not connected
this.operator_name = null;
} else {
- let [bandClass, band, id] = result;
- if (name.length > 0) {
- let table = _getProvidersTable();
- this.operator_name = findProviderForSid(table, id);
- } else
- this.operator_name = null;
+ let [bandClass, band, sid] = result;
+
+ this.operator_name = _findProviderForSid(sid)
}
this.emit('notify::operator-name');
}));
_reload3gppOperatorName: function() {
let name = this._proxy_3gpp.OperatorName;
let code = this._proxy_3gpp.OperatorCode;
- this.operator_name_3gpp = findOperatorName(name, code);
+ this.operator_name_3gpp = _findProviderForMccMnc(name, code);
this._reloadOperatorName();
},
_reloadCdmaOperatorName: function() {
let sid = this._proxy_cdma.Sid;
- this.operator_name_cdma = findProviderForSid(sid);
+ this.operator_name_cdma = _findProviderForSid(sid);
this._reloadOperatorName();
}
});
+++ /dev/null
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301 USA.
- *
- * Copyright (C) 2009 Novell, Inc.
- * Author: Tambet Ingo (tambet@gmail.com).
- *
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include <glib/gi18n.h>
-
-#include "shell-mobile-providers.h"
-
-#ifndef MOBILE_BROADBAND_PROVIDER_INFO
-#define MOBILE_BROADBAND_PROVIDER_INFO DATADIR "/mobile-broadband-provider-info/serviceproviders.xml"
-#endif
-
-#define ISO_3166_COUNTRY_CODES DATADIR "/zoneinfo/iso3166.tab"
-
-static ShellCountryMobileProvider *country_mobile_provider_new (const char *country_code,
- const gchar *country_name);
-
-static GHashTable *
-read_country_codes (const gchar *country_codes)
-{
- GHashTable *table;
- GIOChannel *channel;
- GString *buffer;
- GError *error = NULL;
- GIOStatus status;
-
- channel = g_io_channel_new_file (country_codes, "r", &error);
- if (!channel) {
- if (error) {
- g_warning ("Could not read %s: %s", country_codes, error->message);
- g_error_free (error);
- } else
- g_warning ("Could not read %s: Unknown error", country_codes);
-
- return NULL;
- }
-
- table = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- (GDestroyNotify)shell_country_mobile_provider_unref);
- buffer = g_string_sized_new (32);
-
- status = G_IO_STATUS_NORMAL;
- while (status == G_IO_STATUS_NORMAL) {
- status = g_io_channel_read_line_string (channel, buffer, NULL, &error);
-
- switch (status) {
- case G_IO_STATUS_NORMAL:
- if (buffer->str[0] != '#') {
- ShellCountryMobileProvider *country_provider;
- char **pieces;
-
- pieces = g_strsplit (buffer->str, "\t", 2);
-
- /* Hack for rh#556292; iso3166.tab is just wrong */
- pieces[1] = pieces[1] ? g_strchomp (pieces[1]) : NULL;
- if (pieces[1] && !strcmp (pieces[1], "Britain (UK)")) {
- g_free (pieces[1]);
- pieces[1] = g_strdup (_("United Kingdom"));
- }
-
- country_provider = country_mobile_provider_new (pieces[0], pieces[1]);
- g_hash_table_insert (table, pieces[0], country_provider);
- g_free (pieces);
- }
-
- g_string_truncate (buffer, 0);
- break;
- case G_IO_STATUS_EOF:
- break;
- case G_IO_STATUS_ERROR:
- g_warning ("Error while reading: %s", error->message);
- g_error_free (error);
- break;
- case G_IO_STATUS_AGAIN:
- /* FIXME: Try again a few times, but really, it never happes, right? */
- break;
- }
- }
-
- g_string_free (buffer, TRUE);
- g_io_channel_unref (channel);
-
- return table;
-}
-
-/* XML Parser */
-
-typedef enum {
- PARSER_TOPLEVEL = 0,
- PARSER_COUNTRY,
- PARSER_PROVIDER,
- PARSER_METHOD_GSM,
- PARSER_METHOD_GSM_APN,
- PARSER_METHOD_CDMA,
- PARSER_ERROR
-} MobileContextState;
-
-typedef struct {
- GHashTable *table;
-
- char *current_country;
- GSList *current_providers;
- ShellMobileProvider *current_provider;
- ShellMobileAccessMethod *current_method;
-
- char *text_buffer;
- MobileContextState state;
-} MobileParser;
-
-static ShellGsmMccMnc *
-mcc_mnc_new (const char *mcc, const char *mnc)
-{
- ShellGsmMccMnc *m;
-
- m = g_slice_new (ShellGsmMccMnc);
- m->mcc = g_strstrip (g_strdup (mcc));
- m->mnc = g_strstrip (g_strdup (mnc));
- return m;
-}
-
-/* added in porting */
-static ShellGsmMccMnc *
-mcc_mnc_copy (const ShellGsmMccMnc *other) {
- ShellGsmMccMnc *ret;
-
- ret = g_slice_new (ShellGsmMccMnc);
- ret->mcc = g_strdup (other->mcc);
- ret->mnc = g_strdup (other->mnc);
- return ret;
-}
-
-static void
-mcc_mnc_free (ShellGsmMccMnc *m)
-{
- g_return_if_fail (m != NULL);
- g_free (m->mcc);
- g_free (m->mnc);
- g_slice_free (ShellGsmMccMnc, m);
-}
-
-/* added in porting */
-G_DEFINE_BOXED_TYPE (ShellGsmMccMnc, shell_gsm_mcc_mnc, mcc_mnc_copy, mcc_mnc_free)
-
-static ShellMobileAccessMethod *
-access_method_new (void)
-{
- ShellMobileAccessMethod *method;
-
- method = g_slice_new0 (ShellMobileAccessMethod);
- method->refs = 1;
- method->lcl_names = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_free);
-
- return method;
-}
-
-ShellMobileAccessMethod *
-shell_mobile_access_method_ref (ShellMobileAccessMethod *method)
-{
- g_return_val_if_fail (method != NULL, NULL);
- g_return_val_if_fail (method->refs > 0, NULL);
-
- method->refs++;
-
- return method;
-}
-
-void
-shell_mobile_access_method_unref (ShellMobileAccessMethod *method)
-{
- g_return_if_fail (method != NULL);
- g_return_if_fail (method->refs > 0);
-
- if (--method->refs == 0) {
- g_free (method->name);
- g_hash_table_destroy (method->lcl_names);
- g_free (method->username);
- g_free (method->password);
- g_free (method->gateway);
- g_free (method->gsm_apn);
- g_slist_foreach (method->dns, (GFunc) g_free, NULL);
- g_slist_free (method->dns);
-
- g_slice_free (ShellMobileAccessMethod, method);
- }
-}
-
-GType
-shell_mobile_access_method_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- type = g_boxed_type_register_static ("ShellMobileAccessMethod",
- (GBoxedCopyFunc) shell_mobile_access_method_ref,
- (GBoxedFreeFunc) shell_mobile_access_method_unref);
- }
- return type;
-}
-
-
-static ShellMobileProvider *
-provider_new (void)
-{
- ShellMobileProvider *provider;
-
- provider = g_slice_new0 (ShellMobileProvider);
- provider->refs = 1;
- provider->lcl_names = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_free);
-
- return provider;
-}
-
-ShellMobileProvider *
-shell_mobile_provider_ref (ShellMobileProvider *provider)
-{
- provider->refs++;
-
- return provider;
-}
-
-void
-shell_mobile_provider_unref (ShellMobileProvider *provider)
-{
- if (--provider->refs == 0) {
- g_free (provider->name);
- g_hash_table_destroy (provider->lcl_names);
-
- g_slist_foreach (provider->methods, (GFunc) shell_mobile_access_method_unref, NULL);
- g_slist_free (provider->methods);
-
- g_slist_foreach (provider->gsm_mcc_mnc, (GFunc) mcc_mnc_free, NULL);
- g_slist_free (provider->gsm_mcc_mnc);
-
- g_slist_free (provider->cdma_sid);
-
- g_slice_free (ShellMobileProvider, provider);
- }
-}
-
-GType
-shell_mobile_provider_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- type = g_boxed_type_register_static ("ShellMobileProvider",
- (GBoxedCopyFunc) shell_mobile_provider_ref,
- (GBoxedFreeFunc) shell_mobile_provider_unref);
- }
- return type;
-}
-
-static ShellCountryMobileProvider *
-country_mobile_provider_new (const char *country_code,
- const gchar *country_name)
-{
- ShellCountryMobileProvider *country_provider;
-
- country_provider = g_slice_new0 (ShellCountryMobileProvider);
- country_provider->refs = 1;
- country_provider->country_code = g_strdup (country_code);
- country_provider->country_name = g_strdup (country_name);
- return country_provider;
-}
-
-ShellCountryMobileProvider *
-shell_country_mobile_provider_ref (ShellCountryMobileProvider *country_provider)
-{
- country_provider->refs++;
-
- return country_provider;
-}
-
-void
-shell_country_mobile_provider_unref (ShellCountryMobileProvider *country_provider)
-{
- if (--country_provider->refs == 0) {
- g_free (country_provider->country_code);
- g_free (country_provider->country_name);
- g_slist_free_full (country_provider->providers,
- (GDestroyNotify) shell_mobile_provider_unref);
- g_slice_free (ShellCountryMobileProvider, country_provider);
- }
-}
-
-/**
- * shell_country_mobile_provider_get_country_code:
- *
- * Returns: (transfer none): the code of the country.
- */
-const gchar *
-shell_country_mobile_provider_get_country_code (ShellCountryMobileProvider *country_provider)
-{
- return country_provider->country_code;
-}
-
-/**
- * shell_country_mobile_provider_get_country_name:
- *
- * Returns: (transfer none): the name of the country.
- */
-const gchar *
-shell_country_mobile_provider_get_country_name (ShellCountryMobileProvider *country_provider)
-{
- return country_provider->country_name;
-}
-
-/**
- * shell_country_mobile_provider_get_providers:
- *
- * Returns: (element-type Shell.MobileProvider) (transfer none): the
- * list of #ShellMobileProvider this country exposes.
- */
-GSList *
-shell_country_mobile_provider_get_providers (ShellCountryMobileProvider *country_provider)
-{
- return country_provider->providers;
-}
-
-GType
-shell_country_mobile_provider_get_type (void)
-{
- static GType type = 0;
-
- if (G_UNLIKELY (type == 0)) {
- type = g_boxed_type_register_static ("ShellCountryMobileProvider",
- (GBoxedCopyFunc) shell_country_mobile_provider_ref,
- (GBoxedFreeFunc) shell_country_mobile_provider_unref);
- }
- return type;
-}
-
-static void
-provider_list_free (gpointer data)
-{
- GSList *list = (GSList *) data;
-
- while (list) {
- shell_mobile_provider_unref ((ShellMobileProvider *) list->data);
- list = g_slist_delete_link (list, list);
- }
-}
-
-static void
-parser_toplevel_start (MobileParser *parser,
- const char *name,
- const char **attribute_names,
- const char **attribute_values)
-{
- int i;
-
- if (!strcmp (name, "serviceproviders")) {
- for (i = 0; attribute_names && attribute_names[i]; i++) {
- if (!strcmp (attribute_names[i], "format")) {
- if (strcmp (attribute_values[i], "2.0")) {
- g_warning ("%s: mobile broadband provider database format '%s'"
- " not supported.", __func__, attribute_values[i]);
- parser->state = PARSER_ERROR;
- break;
- }
- }
- }
- } else if (!strcmp (name, "country")) {
- for (i = 0; attribute_names && attribute_names[i]; i++) {
- if (!strcmp (attribute_names[i], "code")) {
- char *country_code;
- ShellCountryMobileProvider *country_provider;
-
- country_code = g_ascii_strup (attribute_values[i], -1);
- country_provider = g_hash_table_lookup (parser->table, country_code);
- /* Ensure we have a country provider for this country code */
- if (!country_provider) {
- g_warning ("%s: adding providers for unknown country '%s'", __func__, country_code);
- country_provider = country_mobile_provider_new (country_code, NULL);
- g_hash_table_insert (parser->table, country_code, country_provider);
- }
- parser->current_country = country_code;
-
- parser->state = PARSER_COUNTRY;
- break;
- }
- }
- }
-}
-
-static void
-parser_country_start (MobileParser *parser,
- const char *name,
- const char **attribute_names,
- const char **attribute_values)
-{
- if (!strcmp (name, "provider")) {
- parser->state = PARSER_PROVIDER;
- parser->current_provider = provider_new ();
- }
-}
-
-static void
-parser_provider_start (MobileParser *parser,
- const char *name,
- const char **attribute_names,
- const char **attribute_values)
-{
- if (!strcmp (name, "gsm"))
- parser->state = PARSER_METHOD_GSM;
- else if (!strcmp (name, "cdma")) {
- parser->state = PARSER_METHOD_CDMA;
- parser->current_method = access_method_new ();
- }
-}
-
-static void
-parser_gsm_start (MobileParser *parser,
- const char *name,
- const char **attribute_names,
- const char **attribute_values)
-{
- if (!strcmp (name, "network-id")) {
- const char *mcc = NULL, *mnc = NULL;
- int i;
-
- for (i = 0; attribute_names && attribute_names[i]; i++) {
- if (!strcmp (attribute_names[i], "mcc"))
- mcc = attribute_values[i];
- else if (!strcmp (attribute_names[i], "mnc"))
- mnc = attribute_values[i];
-
- if (mcc && strlen (mcc) && mnc && strlen (mnc)) {
- parser->current_provider->gsm_mcc_mnc = g_slist_prepend (parser->current_provider->gsm_mcc_mnc,
- mcc_mnc_new (mcc, mnc));
- break;
- }
- }
- } else if (!strcmp (name, "apn")) {
- int i;
-
- for (i = 0; attribute_names && attribute_names[i]; i++) {
- if (!strcmp (attribute_names[i], "value")) {
-
- parser->state = PARSER_METHOD_GSM_APN;
- parser->current_method = access_method_new ();
- parser->current_method->gsm_apn = g_strstrip (g_strdup (attribute_values[i]));
- break;
- }
- }
- }
-}
-
-static void
-parser_cdma_start (MobileParser *parser,
- const char *name,
- const char **attribute_names,
- const char **attribute_values)
-{
- if (!strcmp (name, "sid")) {
- int i;
-
- for (i = 0; attribute_names && attribute_names[i]; i++) {
- if (!strcmp (attribute_names[i], "value")) {
- unsigned long tmp;
-
- errno = 0;
- tmp = strtoul (attribute_values[i], NULL, 10);
- if (errno == 0 && tmp > 0)
- parser->current_provider->cdma_sid = g_slist_prepend (parser->current_provider->cdma_sid,
- GUINT_TO_POINTER ((guint32) tmp));
- break;
- }
- }
- }
-}
-
-static void
-mobile_parser_start_element (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer data,
- GError **error)
-{
- MobileParser *parser = (MobileParser *) data;
-
- if (parser->text_buffer) {
- g_free (parser->text_buffer);
- parser->text_buffer = NULL;
- }
-
- switch (parser->state) {
- case PARSER_TOPLEVEL:
- parser_toplevel_start (parser, element_name, attribute_names, attribute_values);
- break;
- case PARSER_COUNTRY:
- parser_country_start (parser, element_name, attribute_names, attribute_values);
- break;
- case PARSER_PROVIDER:
- parser_provider_start (parser, element_name, attribute_names, attribute_values);
- break;
- case PARSER_METHOD_GSM:
- parser_gsm_start (parser, element_name, attribute_names, attribute_values);
- break;
- case PARSER_METHOD_CDMA:
- parser_cdma_start (parser, element_name, attribute_names, attribute_values);
- break;
- default:
- break;
- }
-}
-
-static void
-parser_country_end (MobileParser *parser,
- const char *name)
-{
- if (!strcmp (name, "country")) {
- ShellCountryMobileProvider *country_provider;
-
- country_provider = g_hash_table_lookup (parser->table, parser->current_country);
- if (country_provider)
- /* Store providers for this country */
- country_provider->providers = parser->current_providers;
-
- parser->current_country = NULL;
- parser->current_providers = NULL;
- parser->text_buffer = NULL;
- parser->state = PARSER_TOPLEVEL;
- }
-}
-
-static void
-parser_provider_end (MobileParser *parser,
- const char *name)
-{
- if (!strcmp (name, "name")) {
- if (!parser->current_provider->name) {
- /* Use the first one. */
- parser->current_provider->name = parser->text_buffer;
- parser->text_buffer = NULL;
- }
- } else if (!strcmp (name, "provider")) {
- parser->current_provider->methods = g_slist_reverse (parser->current_provider->methods);
-
- parser->current_provider->gsm_mcc_mnc = g_slist_reverse (parser->current_provider->gsm_mcc_mnc);
- parser->current_provider->cdma_sid = g_slist_reverse (parser->current_provider->cdma_sid);
-
- parser->current_providers = g_slist_prepend (parser->current_providers, parser->current_provider);
- parser->current_provider = NULL;
- parser->text_buffer = NULL;
- parser->state = PARSER_COUNTRY;
- }
-}
-
-static void
-parser_gsm_end (MobileParser *parser,
- const char *name)
-{
- if (!strcmp (name, "gsm")) {
- parser->text_buffer = NULL;
- parser->state = PARSER_PROVIDER;
- }
-}
-
-static void
-parser_gsm_apn_end (MobileParser *parser,
- const char *name)
-{
- if (!strcmp (name, "name")) {
- if (!parser->current_method->name) {
- /* Use the first one. */
- parser->current_method->name = parser->text_buffer;
- parser->text_buffer = NULL;
- }
- } else if (!strcmp (name, "username")) {
- parser->current_method->username = parser->text_buffer;
- parser->text_buffer = NULL;
- } else if (!strcmp (name, "password")) {
- parser->current_method->password = parser->text_buffer;
- parser->text_buffer = NULL;
- } else if (!strcmp (name, "dns")) {
- parser->current_method->dns = g_slist_prepend (parser->current_method->dns, parser->text_buffer);
- parser->text_buffer = NULL;
- } else if (!strcmp (name, "gateway")) {
- parser->current_method->gateway = parser->text_buffer;
- parser->text_buffer = NULL;
- } else if (!strcmp (name, "apn")) {
- parser->current_method->type = SHELL_MOBILE_ACCESS_METHOD_TYPE_GSM;
- parser->current_method->dns = g_slist_reverse (parser->current_method->dns);
-
- if (!parser->current_method->name)
- parser->current_method->name = g_strdup (_("Default"));
-
- parser->current_provider->methods = g_slist_prepend (parser->current_provider->methods,
- parser->current_method);
- parser->current_method = NULL;
- parser->text_buffer = NULL;
- parser->state = PARSER_METHOD_GSM;
- }
-}
-
-static void
-parser_cdma_end (MobileParser *parser,
- const char *name)
-{
- if (!strcmp (name, "username")) {
- parser->current_method->username = parser->text_buffer;
- parser->text_buffer = NULL;
- } else if (!strcmp (name, "password")) {
- parser->current_method->password = parser->text_buffer;
- parser->text_buffer = NULL;
- } else if (!strcmp (name, "dns")) {
- parser->current_method->dns = g_slist_prepend (parser->current_method->dns, parser->text_buffer);
- parser->text_buffer = NULL;
- } else if (!strcmp (name, "gateway")) {
- parser->current_method->gateway = parser->text_buffer;
- parser->text_buffer = NULL;
- } else if (!strcmp (name, "cdma")) {
- parser->current_method->type = SHELL_MOBILE_ACCESS_METHOD_TYPE_CDMA;
- parser->current_method->dns = g_slist_reverse (parser->current_method->dns);
-
- if (!parser->current_method->name)
- parser->current_method->name = g_strdup (parser->current_provider->name);
-
- parser->current_provider->methods = g_slist_prepend (parser->current_provider->methods,
- parser->current_method);
- parser->current_method = NULL;
- parser->text_buffer = NULL;
- parser->state = PARSER_PROVIDER;
- }
-}
-
-static void
-mobile_parser_end_element (GMarkupParseContext *context,
- const gchar *element_name,
- gpointer data,
- GError **error)
-{
- MobileParser *parser = (MobileParser *) data;
-
- switch (parser->state) {
- case PARSER_COUNTRY:
- parser_country_end (parser, element_name);
- break;
- case PARSER_PROVIDER:
- parser_provider_end (parser, element_name);
- break;
- case PARSER_METHOD_GSM:
- parser_gsm_end (parser, element_name);
- break;
- case PARSER_METHOD_GSM_APN:
- parser_gsm_apn_end (parser, element_name);
- break;
- case PARSER_METHOD_CDMA:
- parser_cdma_end (parser, element_name);
- break;
- default:
- break;
- }
-}
-
-static void
-mobile_parser_characters (GMarkupParseContext *context,
- const gchar *text,
- gsize text_len,
- gpointer data,
- GError **error)
-{
- MobileParser *parser = (MobileParser *) data;
-
- g_free (parser->text_buffer);
- parser->text_buffer = g_strdup (text);
-}
-
-static const GMarkupParser mobile_parser = {
- mobile_parser_start_element,
- mobile_parser_end_element,
- mobile_parser_characters,
- NULL, /* passthrough */
- NULL /* error */
-};
-
-/**
- * shell_mobile_providers_parse:
- * @country_codes: (allow-none) File with the list of country codes.
- * @service_providers: (allow-none) File with the list of service providers.
- *
- * Returns: (element-type utf8 Shell.CountryMobileProvider) (transfer full): a
- * hash table where keys are country names #gchar and values are #ShellCountryMobileProvider.
- * Everything is destroyed with g_hash_table_destroy().
- */
-GHashTable *
-shell_mobile_providers_parse (const gchar *country_codes,
- const gchar *service_providers)
-{
- GMarkupParseContext *ctx;
- GIOChannel *channel;
- MobileParser parser;
- GError *error = NULL;
- char buffer[4096];
- GIOStatus status;
- gsize len = 0;
-
- /* Use default paths if none given */
- if (!country_codes)
- country_codes = ISO_3166_COUNTRY_CODES;
- if (!service_providers)
- service_providers = MOBILE_BROADBAND_PROVIDER_INFO;
-
- memset (&parser, 0, sizeof (MobileParser));
-
- parser.table = read_country_codes (country_codes);
- if (!parser.table)
- goto out;
-
- channel = g_io_channel_new_file (service_providers, "r", &error);
- if (!channel) {
- if (error) {
- g_warning ("Could not read %s: %s", service_providers, error->message);
- g_error_free (error);
- } else
- g_warning ("Could not read %s: Unknown error", service_providers);
-
- goto out;
- }
-
- parser.state = PARSER_TOPLEVEL;
-
- ctx = g_markup_parse_context_new (&mobile_parser, 0, &parser, NULL);
-
- status = G_IO_STATUS_NORMAL;
- while (status == G_IO_STATUS_NORMAL) {
- status = g_io_channel_read_chars (channel, buffer, sizeof (buffer), &len, &error);
-
- switch (status) {
- case G_IO_STATUS_NORMAL:
- if (!g_markup_parse_context_parse (ctx, buffer, len, &error)) {
- status = G_IO_STATUS_ERROR;
- g_warning ("Error while parsing XML: %s", error->message);
- g_error_free (error);;
- }
- break;
- case G_IO_STATUS_EOF:
- break;
- case G_IO_STATUS_ERROR:
- g_warning ("Error while reading: %s", error->message);
- g_error_free (error);
- break;
- case G_IO_STATUS_AGAIN:
- /* FIXME: Try again a few times, but really, it never happes, right? */
- break;
- }
- }
-
- g_io_channel_unref (channel);
- g_markup_parse_context_free (ctx);
-
- if (parser.current_provider) {
- g_warning ("pending current provider");
- shell_mobile_provider_unref (parser.current_provider);
- }
-
- if (parser.current_providers) {
- g_warning ("pending current providers");
- provider_list_free (parser.current_providers);
- }
-
- g_free (parser.current_country);
- g_free (parser.text_buffer);
-
-out:
-
- return parser.table;
-}
-
-static void
-dump_generic (ShellMobileAccessMethod *method)
-{
- GSList *iter;
- GString *dns;
-
- g_print (" username: %s\n", method->username ? method->username : "");
- g_print (" password: %s\n", method->password ? method->password : "");
-
- dns = g_string_new (NULL);
- for (iter = method->dns; iter; iter = g_slist_next (iter))
- g_string_append_printf (dns, "%s%s", dns->len ? ", " : "", (char *) iter->data);
- g_print (" dns : %s\n", dns->str);
- g_string_free (dns, TRUE);
-
- g_print (" gateway : %s\n", method->gateway ? method->gateway : "");
-}
-
-static void
-dump_cdma (ShellMobileAccessMethod *method)
-{
- g_print (" CDMA: %s\n", method->name);
-
- dump_generic (method);
-}
-
-static void
-dump_gsm (ShellMobileAccessMethod *method)
-{
- g_print (" APN: %s (%s)\n", method->name, method->gsm_apn);
-
- dump_generic (method);
-}
-
-static void
-dump_country (gpointer key, gpointer value, gpointer user_data)
-{
- GSList *miter, *citer;
- ShellCountryMobileProvider *country_provider = value;
-
- g_print ("Country: %s (%s)\n",
- country_provider->country_code,
- country_provider->country_name);
-
- for (citer = country_provider->providers; citer; citer = g_slist_next (citer)) {
- ShellMobileProvider *provider = citer->data;
-
- g_print (" Provider: %s (%s)\n", provider->name, (const char *) key);
- for (miter = provider->methods; miter; miter = g_slist_next (miter)) {
- ShellMobileAccessMethod *method = miter->data;
- GSList *liter;
-
-
- for (liter = provider->gsm_mcc_mnc; liter; liter = g_slist_next (liter)) {
- ShellGsmMccMnc *m = liter->data;
- g_print (" MCC/MNC: %s-%s\n", m->mcc, m->mnc);
- }
-
- for (liter = provider->cdma_sid; liter; liter = g_slist_next (liter))
- g_print (" SID: %d\n", GPOINTER_TO_UINT (liter->data));
-
- switch (method->type) {
- case SHELL_MOBILE_ACCESS_METHOD_TYPE_CDMA:
- dump_cdma (method);
- break;
- case SHELL_MOBILE_ACCESS_METHOD_TYPE_GSM:
- dump_gsm (method);
- break;
- default:
- break;
- }
- g_print ("\n");
- }
- }
-}
-
-void
-shell_mobile_providers_dump (GHashTable *country_providers)
-{
- g_return_if_fail (country_providers != NULL);
- g_hash_table_foreach (country_providers, dump_country, NULL);
-}
-
-/* All the following don't exist in nm-applet, because C doesn't need
- those. They're only needed for the introspection annotations
-*/
-
-/**
- * shell_mobile_provider_get_gsm_mcc_mnc:
- * @provider: a #ShellMobileProvider
- *
- * Returns: (element-type Shell.GsmMccMnc) (transfer none): the
- * list of #ShellGsmMccMnc this provider exposes
- */
-GSList *
-shell_mobile_provider_get_gsm_mcc_mnc (ShellMobileProvider *provider)
-{
- return provider->gsm_mcc_mnc;
-}
-
-/**
- * shell_mobile_provider_get_cdma_sid:
- * @provider: a #ShellMobileProvider
- *
- * Returns: (element-type guint32) (transfer none): the
- * list of CDMA sids this provider exposes
- */
-GSList *
-shell_mobile_provider_get_cdma_sid (ShellMobileProvider *provider)
-{
- return provider->cdma_sid;
-}